#ifndef _VIEW_MSG_H
#define _VIEW_MSG_H

#include<lib/type.h>
#include<os/msgpool.h>

typedef enum
{
    VIEW_MSG_NONE = 0,
    VIEW_MSG_KEY_DOWN,
    VIEW_MSG_KEY_UP,
    VIEW_MSG_MOUSE_LBTN_DOWN,
    VIEW_MSG_MOUSE_LBTN_UP,
    VIEW_MSG_MOUSE_LBTN_DCLICK,
    VIEW_MSG_MOUSE_MOTION,
    VIEW_MSG_MOUSE_MBTN_DOWN,
    VIEW_MSG_MOUSE_MBTN_UP,
    VIEW_MSG_MOUSE_MBTN_DCLICK,
    VIEW_MSG_MOUSE_RBTN_DOWN,
    VIEW_MSG_MOUSE_RBTN_UP,
    VIEW_MSG_MOUSE_RBTN_DCLICK,
    VIWE_MSG_MOUSE_WHEEL_DOWN,  //wheel to down
    VIEW_MSG_MOUSE_WHEEL_UP,    //wheel to up
    VIEW_MSG_MOUSE_WHEEL_LEFT,  //wheel to left
    VIEW_MSG_MOUSE_WHEEL_RIGHT, //wheel to right
    VIEW_MSG_TIMER,
    VIEW_MSG_QUIT,
    VIEW_MSG_ENTER,
    VIEW_MSG_LEAVE,
    VIEW_MSG_RESIZE,
    VIEW_MSG_ACTIVATE,
    VIEW_MSG_INACTIVATE,
    VIEW_MSG_MOVE,
    VIEW_MSG_CREATE,
    VIEW_MSG_CLOSE,
    VIEW_MSG_HIDE,
    VIEW_MSG_SHOW,
    VIEW_MSG_PAINT,
    VIEW_MSG_SETICON,
    VIEW_MSG_NUM,
} view_msg_type;

//view default targe
#define VIEW_TARGE_NONE -1

//view msg flags
#define VIEW_MSG_NOWAIT 0x01

#define IsViewMsgVaild(msg) ((msg)->id>VIEW_MSG_NONE&&(msg)->id<VIEW_MSG_NUM)

#define ViewMsgGetId(msg) ((msg)->id)

//view msg opertor
#define ViewMsgGetMouseX(msg) ((msg)->data0)
#define ViewMsgGetMouseY(msg) ((msg)->data1)

#define ViewMsgGetMouseWheel(msg) ((msg)->data2)

#define ViewMsgGetKeyCode(msg) ((msg)->data0)
#define ViewMsgGetKeyModify(msg) ((msg)->data1)

#define ViewMsgGetTimerId(msg) ((msg)->data0)
#define ViewMsgGetTimerTime(msg) ((msg)->data1)

typedef struct
{
    uint32_t id; //msg id
    int targe;   //msg targe

    uint32_t data0;
    uint32_t data1;
    uint32_t data2;
    uint32_t data3;
} view_msg_t;

static inline void ViewMsgHeader(view_msg_t *msg, uint32_t id, int targe)
{
    msg->id = id;
    msg->targe = targe;
}

static inline void ViewMsgData(view_msg_t *msg, uint32_t data0, uint32_t data1, uint32_t data2, uint32_t data3)
{
    msg->data0 = data0;
    msg->data1 = data1;
    msg->data2 = data2;
    msg->data3 = data3;
}

static inline void ViewMsgReset(view_msg_t *msg)
{
    msg->id = 0;
    msg->targe = -1;
    msg->data0 = 0;
    msg->data1 = 0;
    msg->data2 = 0;
    msg->data3 = 0;
}

extern msgpool_t *view_global_msgpool;

static inline int ViewGetGlobalMsg(view_msg_t *msg)
{
    return MsgpoolTryGet(view_global_msgpool, msg, NULL);
}

static inline int ViewPutGlobalMsg(view_msg_t *msg)
{
    return MsgpoolTryPut(view_global_msgpool, msg, sizeof(view_msg_t));
}

int ViewGlobalMsgInit();
void ViewGlobalMsgExit();
int ViewDispatchKeycodeMsg(view_msg_t *msg);
int ViewDispatchMouseMsg(view_msg_t *msg);
int ViewDispatchTargeMsg(view_msg_t *msg);



#endif